x86/mm: early put_page when XENMEM_add_to_physmap(XENMAPSPACE_gmfn)
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 24 Dec 2009 09:06:12 +0000 (09:06 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 24 Dec 2009 09:06:12 +0000 (09:06 +0000)
When using a stub domain, xen massively complains as follows:

(XEN) sh error: sh_remove_all_mappings(): can't find all mappings of
mfn be=
3c5: c=3D8000000000000004 t=3D00000000
(XEN) sh error: sh_remove_all_mappings(): can't find all mappings of
mfn be=
3c4: c=3D8000000000000004 t=3D00000000
...

This comes from the XENMEM_add_to_physmap hypercall from hvmloader.

The guest_physmap_remove_page function calls sh_remove_all_mappings()
which checks reference count of the page. Then, calling
guest_physmap_remove_page after temporarily get_page is obviously
wrong. And early put_page is harmless here since domain_lock is
acquired.

Also, the restore program seems not to complain extra mappings
long before. Instead, the stub domain does. Thus the comment in
sh_remove_all_mappings() is rewritten.

Signed-off-by: Kouya Shimura <kouya@jp.fujitsu.com>
xen/arch/x86/mm.c
xen/arch/x86/mm/shadow/common.c

index 9eec698ae49a99df2d84ca50d1558b27f45ecd61..b9d5d49d224b2349051019ce2b95b8bea47cec5d 100644 (file)
@@ -4304,6 +4304,9 @@ long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg)
 
         domain_lock(d);
 
+        if ( page )
+            put_page(page);
+
         /* Remove previously mapped page if it was present. */
         prev_mfn = gmfn_to_mfn(d, xatp.gpfn);
         if ( mfn_valid(prev_mfn) )
@@ -4327,9 +4330,6 @@ long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg)
 
         domain_unlock(d);
 
-        if ( page )
-            put_page(page);
-
         rcu_unlock_domain(d);
 
         return rc;
index 434d56753688ca10720ecb7b36cf8d5b5c5c7392..4c0d084902737366af3af7bc728e4f24c994199d 100644 (file)
@@ -2606,7 +2606,7 @@ int sh_remove_all_mappings(struct vcpu *v, mfn_t gmfn)
     {
         /* Don't complain if we're in HVM and there are some extra mappings: 
          * The qemu helper process has an untyped mapping of this dom's RAM 
-         * and the HVM restore program takes another. */
+         * and the stub domain takes another. */
         if ( !(shadow_mode_external(v->domain)
                && (page->count_info & PGC_count_mask) <= 3
                && (page->u.inuse.type_info & PGT_count_mask) == 0) )